/*
 * @(#)FindSubmissionSetsRunner.java
 * Date 2013-09-02
 * Version 1.0
 * Author Jim Horner
 * Copyright (c)2012
 */


package us.hornerscorners.lamppost.registry.query.es;

import java.util.HashMap;
import java.util.Map;

import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;

import us.hornerscorners.lamppost.ihecommon.config.IHEConfig;

import us.hornerscorners.lamppost.ihecommon.service.ElasticSearchSource;

import us.hornerscorners.lamppost.model.common.PersistableModelType;

import us.hornerscorners.lamppost.registry.constant.QueryField;
import us.hornerscorners.lamppost.registry.constant.QuerySlotName;

import us.hornerscorners.lamppost.registry.model.QueryRequest;

import us.hornerscorners.lamppost.registry.transformer.model.CodedElementTransformer;
import us.hornerscorners.lamppost.registry.transformer.model.PatientIdentifierTransformer;


/**
 * Class description
 *
 *
 * @version        v1.0, 2013-09-02
 * @author         Jim Horner
 */
public class FindSubmissionSetsRunner extends AbstractQueryRunner {

    /**
     * Constructs ...
     *
     *
     * @param config
     * @param elasticSearchSource
     * @param codedElementTransformer
     * @param patientIdentifierTransformer
     */
    public FindSubmissionSetsRunner(
            IHEConfig config, ElasticSearchSource elasticSearchSource,
            CodedElementTransformer codedElementTransformer,
            PatientIdentifierTransformer patientIdentifierTransformer) {

        super(config, elasticSearchSource, codedElementTransformer,
              patientIdentifierTransformer);

    }

    /**
     * Method description
     *
     *
     * @param request
     *
     * @return
     */
    @Override
    public Map<PersistableModelType, QueryBuilder> createQuery(QueryRequest request) {

        Map<PersistableModelType, QueryBuilder> result = new HashMap<>();

        BoolQueryBuilder query = QueryBuilders.boolQuery();

        result.put(PersistableModelType.SubmissionSet, query);

        // patient id (required)
        query.must(createPatientIdentifierQuery(request,
                QuerySlotName.XDSSubmissionSetPatientId,
                QueryField.SubmissionSetPatientIdRoot,
                QueryField.SubmissionSetPatientIdExtension));

        // availability status (required)
        query.must(createStringQuery(request, QuerySlotName.XDSSubmissionSetStatus,
                                     QueryField.SubmissionSetAvailabilityStatus));

        // source id
        if (request.hasValues(QuerySlotName.XDSSubmissionSetSourceId)) {

            query.must(createStringQuery(request, QuerySlotName.XDSSubmissionSetSourceId,
                                         QueryField.SubmissionSetSourceId));
        }

        // submission time
        if (request.hasValues(QuerySlotName.XDSSubmissionSetSubmissionTimeFrom)
                || request.hasValues(QuerySlotName.XDSSubmissionSetSubmissionTimeTo)) {

            query.must(createTimeQuery(request,
                                       QuerySlotName.XDSSubmissionSetSubmissionTimeFrom,
                                       QuerySlotName.XDSSubmissionSetSubmissionTimeTo,
                                       QueryField.SubmissionSetSubmissionTime));
        }

        // content type
        if (request.hasValues(QuerySlotName.XDSSubmissionSetContentType)) {

            query.must(
                createCodedElementQuery(
                    request, QuerySlotName.XDSSubmissionSetContentType,
                    QueryField.SubmissionSetContentTypeCode,
                    QueryField.SubmissionSetContentTypeScheme));
        }

        if (request.hasValues(QuerySlotName.XDSSubmissionSetContentTypeScheme)) {

            query.must(createStringQuery(request,
                                         QuerySlotName.XDSSubmissionSetContentTypeScheme,
                                         QueryField.SubmissionSetContentTypeScheme));
        }

        // author person
        if (request.hasValues(QuerySlotName.XDSSubmissionSetAuthorPerson)) {

            query.must(createStringQuery(request,
                                         QuerySlotName.XDSSubmissionSetAuthorPerson,
                                         QueryField.SubmissionSetAuthorPersons));
        }

        return result;
    }
}
